using System;
using System.Reflection;
using System.Threading;
using Cysharp.Threading.Tasks;
using GameFramework.Reference;
using GameFramework.Request;

namespace GameFramework.UI.FairyGUI
{
    /// <summary>
    /// FairyGUI UI请求抽象类
    /// </summary>
    public abstract class AFairyGUIRequest<T> : AUIRequest where T : AFairyGUIFormLogic
    {
        protected sealed override string UIKey { get; }

        protected AFairyGUIRequest()
        {
            var attribute = typeof(T).GetCustomAttribute<FairyGUIFormAttribute>();
            if (attribute == null)
            {
                Log.Error($"UIKey is null, type: {typeof(T).FullName}");
                return;
            }

            UIKey = attribute.UIKey;
        }
    }

    public abstract class AFairyGUIRequest<TRequest, TForm> : AFairyGUIRequest<TForm>
        where TRequest : AFairyGUIRequest<TRequest, TForm>, new()
        where TForm : AFairyGUIFormLogic
    {
        public static UniTask<IResponse> OpenForm(Action<TRequest> settings, CancellationToken token)
        {
            return Reference.ReferenceService.That.GetReference(settings).Execute(token);
        }

        public static UniTask<IResponse> OpenForm(Action<TRequest> settings)
        {
            return Reference.ReferenceService.That.GetReference(settings).Execute();
        }

        public static UniTask<IResponse> OpenForm(CancellationToken token)
        {
            return Reference.ReferenceService.That.GetReference<TRequest>().Execute(token);
        }

        public static UniTask<IResponse> OpenForm()
        {
            return Reference.ReferenceService.That.GetReference<TRequest>().Execute();
        }
        
        public static UniTask<TResponse> OpenForm<TResponse>(Action<TRequest> settings, CancellationToken token) where TResponse : AResponse, new()
        {
            return Reference.ReferenceService.That.GetReference(settings).Execute<TResponse>(token);
        }
        
        public static UniTask<TResponse> OpenForm<TResponse>(Action<TRequest> settings) where TResponse : AResponse, new()
        {
            return Reference.ReferenceService.That.GetReference(settings).Execute<TResponse>();
        }
        
        public static UniTask<TResponse> OpenForm<TResponse>(CancellationToken token) where TResponse : AResponse, new()
        {
            return Reference.ReferenceService.That.GetReference<TRequest>().Execute<TResponse>(token);
        }
        
        public static UniTask<TResponse> OpenForm<TResponse>() where TResponse : AResponse, new()
        {
            return Reference.ReferenceService.That.GetReference<TRequest>().Execute<TResponse>();
        }
    }
}